package com.pangu.core.engine.game.task.niuniu;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.cache2k.expiry.ValueWithExpiryTime;

import com.pangu.core.BMDataContext;
import com.pangu.core.cache.CacheHelper;
import com.pangu.core.engine.game.ActionTaskUtils;
import com.pangu.core.engine.game.BeiMiGameEvent;
import com.pangu.core.engine.game.BeiMiGameTask;
import com.pangu.core.engine.game.ChessGameEngine;
import com.pangu.core.engine.game.model.PlayerRecordNiuniu;
import com.pangu.core.engine.game.model.Summary;
import com.pangu.core.engine.game.model.SummaryPlayer;
import com.pangu.core.engine.game.task.AbstractTask;
import com.pangu.util.ProcessCard;
import com.pangu.util.UKTools;
import com.pangu.util.disruptor.DisruptorHandler;
import com.pangu.util.rules.model.GameHistoryBoard;
import com.pangu.util.rules.model.GameStatus;
import com.pangu.util.rules.model.NiuniuBoard;
import com.pangu.util.rules.model.NiuniuPosition;
import com.pangu.web.model.GameBonusPool;
import com.pangu.web.model.GameRoom;
import com.pangu.web.model.PlayUserClient;
import com.pangu.web.service.repository.es.PlayUserClientESRepository;
import com.pangu.web.service.repository.es.PlayerRecordNiuNiuESRepository;
import com.pangu.web.service.repository.jpa.PlayUserClientRepository;
import com.pangu.web.service.repository.jpa.PlayerRecordNiuNiuRepository;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class NiuniuEndTask extends AbstractTask implements ValueWithExpiryTime, BeiMiGameTask {

	@Override
	public void execute() {
		long begin = System.currentTimeMillis();
		NiuniuBoard board = (NiuniuBoard) CacheHelper.getBoardCacheBean().getCacheObject(gameRoom.getId(),
				gameRoom.getOrgi());
		List<PlayUserClient> plays = CacheHelper.getGamePlayerCacheBean().getCacheObject(gameRoom.getId(), orgi);
		// 1.保存结算日志信息
		Summary sm = saveRecord(board, plays);// 闲家
		sendEvent(sm.getCommand(), sm, gameRoom);// 发送结算数据
		// 2.清除已经托管的用户以及ai钱数不够的用户
		BMDataContext.getContext().getBean(ChessGameEngine.class).leaveRoom(gameRoom.getId(), orgi);
		// 3.完成该局游戏
		BMDataContext.getContext().getBean(ChessGameEngine.class).finished(gameRoom,plays,BMDataContext.GameTypeEnum.NIUNIU.toString());
		// 4.发送top6给前端，并且更新前六的名单
		BMDataContext.getContext().getBean(ChessGameEngine.class).updateTop(gameRoom.getId(), orgi);
		// 5.通知前端
		GameStatus status = new GameStatus(BMDataContext.GameStatusEnum.END.toString(), "游戏结束，等待10秒钟进行下一局");
		status.setCommand(BMDataContext.BEIMI_GAMESTATUS_EVENT);
		ActionTaskUtils.sendEvent(BMDataContext.BEIMI_GAMESTATUS_EVENT, status, gameRoom);
		//6.生成历史记录
		this.saveHistory(board);
		//7.end 持久化
		CacheHelper.getGameStatusCacheBean().put(gameRoom.getRoomid(), status, gameRoom.getOrgi());
		super.getGame(gameRoom.getPlayway(), orgi).change(gameRoom, BeiMiGameEvent.DEAL.toString(),
				BMDataContext.GAME_NEXT_TIME);
		long end = System.currentTimeMillis();
		log.info("结算消耗时间：{}s", (end - begin) / 1000);
	}

	/*
	 * 保存历史记录
	 */
	public void saveHistory(NiuniuBoard board) {
		NiuniuPosition[] np = board.getNiuniuPosition();
		StringBuilder sb = new StringBuilder();
		for (int i = 1; i < np.length; i++) {
			sb.append(np[i].getOdds() > 0 ? 1 : 0).append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		// 存入牌局信息
		GameHistoryBoard gameHistoryBoard = new GameHistoryBoard(board.getId());
		gameHistoryBoard.setCreateTime(new Date());
		gameHistoryBoard.setRoomId(gameRoom.getId());
		gameHistoryBoard.setWinner(sb.toString());
		CacheHelper.getGameHistoryBoardCache().put(gameHistoryBoard.getId(), gameHistoryBoard, gameRoom.getOrgi());
	}

	
	/*
	 * 结算保存数据，从下注记录里面去取
	 */
	public Summary saveRecord(NiuniuBoard board, List<PlayUserClient> plays) {
		// 获取牌局
		// 获取玩家
		if (plays == null) {// 玩家是允许为空的。
			return null;
		}
		
		Summary s = new Summary();
		s.setBoard(board.getId());
		s.setGame(gameRoom.getId());
		List<SummaryPlayer> players = new ArrayList<>();
		s.setCommand(BMDataContext.BEIMI_SETTLEMENT_EVENT);
		NiuniuPosition[] p = board.getNiuniuPosition();
		double blank_coins = 0;
		PlayUserClient playUserClient_blank = null;
		// 结算真人
		for (PlayUserClient playUserClient : plays) {
			if (playUserClient.isBlank()) {
				playUserClient_blank = playUserClient;
				continue;// 先解决庄家
			}
			double intMoney = playUserClient.getGoldcoins();
			List<PlayerRecordNiuniu> record = (List<PlayerRecordNiuniu>) CacheHelper.getGameRecordNiuNiuCacheBean()
					.getCacheObject(playUserClient.getId(), orgi);
			if (record == null) {
				continue;// 然后解决吃瓜群众的问题
			}
			for (PlayerRecordNiuniu playerRecord : record) {
				for (NiuniuPosition niuniuPosition : p) {
					if (playerRecord.getGameSubType() == null || playerRecord.getCoin() <= 0
							|| playerRecord.getCoin() > playUserClient.getGoldcoins()
							|| "0".equals(playerRecord.getGameSubType())) {
						log.info("没有下注或者下注记录超过本金，无法结算");
						continue;
					}

					if (niuniuPosition.getPosition() == Integer.parseInt(playerRecord.getGameSubType())) {
						//log.info("用户{}原始金额：{}", playUserClient.getId(), playUserClient.getGoldcoins());
						//log.info("该用户该局输赢倍数：{}", niuniuPosition.getOdds());
						//log.info("该用户该局下注金额：{}", playerRecord.getCoin());
						double tem = playerRecord.getCoin() * niuniuPosition.getOdds();
						playerRecord.setCards(ProcessCard.byteCardToString(niuniuPosition.getCards()));
						playerRecord.setWinLoseCoin(tem);
						playerRecord.setRoomId(gameRoom.getRoomid());
						//log.info("该用户输赢：{}", tem);
						playUserClient.setGoldcoins(playUserClient.getGoldcoins() + tem);
						//log.info("用户{}结算后金额：{}", playUserClient.getId(),
							//	playUserClient.getGoldcoins() + (new Double(tem)).intValue());
						playerRecord.setGameId(board.getId());
						playerRecord.setSummaryId(UKTools.getUUID());
						;
						// 持久化
						DisruptorHandler.published(playerRecord,
								BMDataContext.getContext().getBean(PlayerRecordNiuNiuESRepository.class),
								BMDataContext.getContext().getBean(PlayerRecordNiuNiuRepository.class));
						CacheHelper.getApiUserCacheBean().put(playUserClient.getId(), playUserClient, orgi); // 持久化用户数据
						CacheHelper.getGamePlayerCacheBean().put(playUserClient.getId(), playUserClient, orgi);
					}
				}
			}
			
			SummaryPlayer sp = new SummaryPlayer();
			double rest = playUserClient.getGoldcoins();
			double winlose = rest-intMoney;
			blank_coins=blank_coins+winlose;
			sp.setBalance(rest);
			sp.setScore(winlose);
			sp.setUserid(playUserClient.getId());
			sp.setUsername(playUserClient.getUsername());
			sp.setWin(winlose>0?true:false);
			//所剩金额
			players.add(sp);

			ActionTaskUtils.sendEvent(BMDataContext.BEIMI_MESSAGE_EVENT, playUserClient.getId(), playUserClient);
			DisruptorHandler.published(playUserClient, BMDataContext.getContext().getBean(PlayUserClientESRepository.class),
					BMDataContext.getContext().getBean(PlayUserClientRepository.class));
		}
		if (playUserClient_blank == null) {
			// 若庄家为空，或者金额出现负数 则要回滚之前所有的数据
			log.info("无法获取到庄家································");
			s.setPlayers(players );
			return s;
		}
		
	

		// 记录日志
		PlayerRecordNiuniu pr = new PlayerRecordNiuniu();
		pr.setGameId(board.getId());
		pr.setRoomId(gameRoom.getId());
		pr.setOrgi(orgi);
		pr.setCards(ProcessCard.byteCardToString(p[0].getCards()));
		pr.setCoin(blank_coins);
		pr.setGameSubType("0");
		pr.setIsBanker(0 + "");
		pr.setPlayerType(playUserClient_blank.getPlayertype());
		pr.setPlayerId(playUserClient_blank.getId());
		pr.setWinLoseCoin(-blank_coins);
		pr.setSummaryId(UKTools.getUUID());
		DisruptorHandler.published(pr, BMDataContext.getContext().getBean(PlayerRecordNiuNiuESRepository.class),
				BMDataContext.getContext().getBean(PlayerRecordNiuNiuRepository.class));
		//log.info("庄家用户{}原始金额：{}", playUserClient_blank.getId(), playUserClient_blank.getGoldcoins());
		//log.info("庄家用户{}结算后金额：{}", playUserClient_blank.getId(),
		//		playUserClient_blank.getGoldcoins() - blank_coins);
		playUserClient_blank.setGoldcoins(playUserClient_blank.getGoldcoins() - blank_coins);
		CacheHelper.getApiUserCacheBean().put(playUserClient_blank.getId(), playUserClient_blank, orgi);
		CacheHelper.getGamePlayerCacheBean().put(playUserClient_blank.getId(), playUserClient_blank, orgi);
		// 持久化用户数据
		DisruptorHandler.published(playUserClient_blank,
				BMDataContext.getContext().getBean(PlayUserClientESRepository.class),
				BMDataContext.getContext().getBean(PlayUserClientRepository.class));
		
		
		SummaryPlayer sp_blank = new SummaryPlayer();
		sp_blank.setBalance(playUserClient_blank.getGoldcoins());
		sp_blank.setScore(-blank_coins);
		sp_blank.setUserid(playUserClient_blank.getId());
		sp_blank.setUsername(playUserClient_blank.getUsername());
		sp_blank.setWin(-blank_coins>0?true:false);
		sp_blank.setDizhu(true);
		players.add(sp_blank);
	
		board.setFinished(true);
		//@ FIXME 测试时没有扣除AI的输赢，记得上线时候修改。更新奖金池
		BMDataContext.getContext().getBean(ChessGameEngine.class).updateGameBonusPool(
				BMDataContext.GameTypeEnum.NIUNIU.toString().toLowerCase(), -(new Double(blank_coins)).intValue(),
				orgi);

		GameBonusPool coin = (GameBonusPool) CacheHelper.getGameBonusPoolCacheBean()
				.getCacheObject(BMDataContext.GameTypeEnum.NIUNIU.toString().toLowerCase(), BMDataContext.SYSTEM_ORGI);
		log.info("奖金池大小：{}", coin.getCoin());
		s.setPlayers(players );
		return s;
		

	}

	private long timer;
	private GameRoom gameRoom = null;
	private String orgi;

	public NiuniuEndTask(long timer, GameRoom gameRoom, String orgi) {
		super();
		this.timer = timer;
		this.gameRoom = gameRoom;
		this.orgi = orgi;
	}

	@Override
	public long getCacheExpiryTime() {
		return System.currentTimeMillis() + timer * 1000; // 5秒后执行
	}

}
